<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // Promise.resolve reject race
      // Promise.all   Promise.allSettled
      // 一、Promise.all(): 可以执行多个Promise对象，获取promise对象的结果
      // all 是同时执行promise对象
      // all 收集的结果，必须都是成功的，如果失败了就收集不到最终的结果
      //   function fn() {
      //     return new Promise((resolve) => {
      //       setTimeout(() => {
      //         resolve(1111);
      //       }, 2000);
      //     });
      //   }

      //   function fn2() {
      //     return new Promise((resolve) => {
      //       setTimeout(() => {
      //         resolve(222);
      //       }, 2000);
      //     });
      //   }

      //   链式：依次执行，一共三秒，时间是相加的
      //   fn()
      //     .then((res) => {
      //       console.log(res);
      //       return fn2();
      //     })
      //     .then((res) => {
      //       console.log(res);
      //     });

      // fn()和fn2() 是同时进行的
      //   fn2().then((res) => {
      //     console.log(res);
      //   });

      //   let p1 = new Promise((resolve, reject) => {
      //     setTimeout(() => {
      //       resolve(111);
      //     }, 2000);
      //   });

      //   let p2 = new Promise((resolve, reject) => {
      //     setTimeout(() => {
      //       resolve(222);
      //       //   reject("222err");
      //     }, 1000);
      //   });

      //   let p3 = new Promise((resolve, reject) => {
      // setTimeout(() => {
      // resolve(333);
      // reject("333err");
      // }, 2000);
      // });

      //  Promise.all 有错误就会马上获取错误，停止向下执行，
      //  只有全部正确才会获取最终结果，
      // 当有实例对象没有resolve和reject时，无法获取结果，但不报错
      //   Promise.all([p1, p2, p3])
      //     .then((res) => {
      //       console.log(res);
      //     })
      //     .catch((err) => {
      //       console.log(err);
      //     });

      //   Promise.all的实现
      /*
        Promise.all的实现流程：
            promise对象以数组的形式传入进行遍历，提取出来Promise对象的结果值，用计数法 count === arr.length 来结束，收集结果完毕！
      */

      class MyPromise {
        static all(arr) {
          return new Promise((resolve, reject) => {
            // resolve[[1111,2222,3333]]
            // 计数法：计算then的执行次数
            let count = 0;

            let resultArr = []; //收集传入进来的promse对象的结果值
            arr.forEach((item) => {
              item.then(
                (res) => {
                  // 数组里的promise对象成功了，需要通过数组收集起来
                  resultArr.push(res);
                  count++;
                  // console.log(resultArr.count);
                  if (count === arr.length) {
                    // 结果收集完毕了，通过resolve返还最后的结果值
                    resolve(resultArr);
                  }
                },
                (err) => {
                  // 如果失败了，直接调用reject；
                  reject(err);
                }
              );
            });
          });
        }
      }

      let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(111);
        }, 2000);
      });

      let p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(222);
        }, 1000);
      });

      let p3 = new Promise((resolve, reject) => {
        setTimeout(() => {
          //   resolve(333);
          reject("333err");
        }, 2000);
      });

      MyPromise.all([p1, p2, p3]).then(
        (res) => {
          console.log(res);
        },
        (err) => {
          console.log(err);
        }
      );
    </script>
  </body>
</html>
